home *** CD-ROM | disk | FTP | other *** search
- {$S-,R-,V-,I-,N-,B-,F-}
-
- {$IFNDEF Ver40}
- {Allow overlays}
- {$F+,O-,X+,A-}
- {$ENDIF}
-
- UNIT CritErr;
-
- INTERFACE
-
- USES DOS;
-
- TYPE
- Str10 = STRING[10];
- IOErrorRec = Record
- RoutineName : PathStr;
- ErrorAddr : Str10;
- ErrorType : Str10;
- TurboResult : Word; { TP Error number }
- IOResult : Word; { DOS Extended number }
- ErrMsg : PathStr;
- End;
-
-
- {}PROCEDURE IOResultTOErrorMessage (IOCode : WORD; VAR MSG : STRING);
- {}PROCEDURE GetDOSErrorMessage (VAR Msg : STRING);
- {}FUNCTION UserIOError(ErrNum : INTEGER; VAR IOErr : IOErrorRec) : BOOLEAN;
- {}PROCEDURE CriticalErrorDOS;
- {}PROCEDURE CriticalErrorTP;
- {}PROCEDURE CriticalErrorOwn(ErrAddr: POINTER);
-
- IMPLEMENTATION
-
- VAR
- TurboInt24: POINTER; { Holds address of TP's error handler }
-
- function Hex(v: Longint; w: Integer): String;
- var
- s : String;
- i : Integer;
- const
- hexc : array [0 .. 15] of Char= '0123456789abcdef';
- begin
- s[0] := Chr(w);
- for i := w downto 1 do begin
- s[i] := hexc[v and $F];
- v := v shr 4
- end;
- Hex := s;
- end {Hex};
-
-
- PROCEDURE CriticalErrorDOS;
-
- BEGIN
- SetIntVec($24,SaveInt24);
- END;
-
-
-
- PROCEDURE CriticalErrorTP;
-
- BEGIN
- SetIntVec($24,TurboInt24);
- END;
-
-
-
- PROCEDURE CriticalErrorOwn(ErrAddr: POINTER);
-
- BEGIN
- SetIntVec($24,ErrAddr);
- END;
-
-
-
- PROCEDURE GetDOSErrorMessage (VAR Msg : STRING);
-
- TYPE pointerwords =
- RECORD
- ofspoint, segpoint : WORD;
- END;
-
- VAR
- breakdown : pointerwords ABSOLUTE erroraddr;
-
- BEGIN
- IOResultToErrorMessage (ExitCode, MSG);
- WITH breakdown DO
- Msg := Msg + ' $' + hex (SegPoint, 4) + ':' + hex (OfsPoint, 4);
- END; {Exitprogram}
-
- PROCEDURE IOResultToErrorMessage (IOCode : WORD; VAR MSG : STRING);
- BEGIN
- CASE IOCode OF
- $01 : msg := 'Invalid DOS Function Number';
- $02 : msg := 'File not found ';
- $03 : msg := 'Path not found ';
- $04 : msg := 'Too many open files ';
- $05 : msg := 'File access denied ';
- $06 : msg := 'Invalid file handle ';
- $07 : msg := 'Memory Control Block Destroyed';
- $08 : msg := 'Not Enough Memory';
- $09 : msg := 'Invalid Memory Block Address';
- $0A : msg := 'Environment Scrambled';
- $0B : msg := 'Bad Program EXE File';
- $0C : msg := 'Invalid file access mode';
- $0D : msg := 'Invalid Data';
- $0E : msg := 'Unknown Unit';
- $0F : msg := 'Invalid drive number ';
- $10 : msg := 'Cannot remove current directory';
- $11 : msg := 'Cannot rename across drives';
- $12 : msg := 'Disk Read/Write Error';
- $13 : msg := 'Disk Write-Protected';
- $14 : msg := 'Unknown Unit';
- $15 : msg := 'Drive Not Ready';
- $16 : msg := 'Unknown Command';
- $17 : msg := 'Data CRC Error';
- $18 : msg := 'Bad Request Structure Length';
- $19 : msg := 'Seek Error';
- $1A : msg := 'Unknown Media Type';
- $1B : msg := 'Sector Not Found';
- $1C : msg := 'Printer Out Of Paper';
- $1D : msg := 'Disk Write Error';
- $1E : msg := 'Disk Read Error';
- $1F : msg := 'General Failure';
- $20 : msg := 'Sharing Violation';
- $21 : msg := 'Lock Violation';
- $22 : msg := 'Invalid Disk Change';
- $23 : msg := 'File Control Block Gone';
- $24 : msg := 'Sharing Buffer Exceeded';
- $32 : msg := 'Unsupported Network Request';
- $33 : msg := 'Remote Machine Not Listening';
- $34 : msg := 'Duplicate Network Name';
- $35 : msg := 'Network Name NOT Found';
- $36 : msg := 'Network BUSY';
- $37 : msg := 'Device No Longer Exists On NETWORK';
- $38 : msg := 'NetBIOS Command Limit Exceeded';
- $39 : msg := 'Adapter Hardware ERROR';
- $3A : msg := 'Incorrect Response From NETWORK';
- $3B : msg := 'Unexpected NETWORK Error';
- $3C : msg := 'Remote Adapter Incompatible';
- $3D : msg := 'Print QUEUE FULL';
- $3E : msg := 'No space For Print File';
- $3F : msg := 'Print File Cancelled';
- $40 : msg := 'Network Name Deleted';
- $41 : msg := 'Network Access Denied';
- $42 : msg := 'Incorrect Network Device Type';
- $43 : msg := 'Network Name Not Found';
- $44 : msg := 'Network Name Limit Exceeded';
- $45 : msg := 'NetBIOS session limit exceeded';
- $46 : msg := 'Filer Sharing temporarily paused';
- $47 : msg := 'Network Request Not Accepted';
- $48 : msg := 'Print or Disk File Paused';
- $50 : msg := 'File Already Exists';
- $52 : msg := 'Cannot Make Directory';
- $53 : msg := 'Fail On Critical Error';
- $54 : msg := 'Too Many Redirections';
- $55 : msg := 'Duplicate Redirection';
- $56 : msg := 'Invalid Password';
- $57 : msg := 'Invalid Parameter';
- $58 : msg := 'Network Device Fault';
- $59 : msg := 'Function Not Supported By NETWORK';
- $5A : msg := 'Required Component NOT Installed';
-
- (* Pascal Errors *)
- 94 : msg := 'EMS Memory Swap Error';
- 98 : msg := 'Disk Full';
- 100 : msg := 'Disk read error ';
- 101 : msg := 'Disk write error ';
- 102 : msg := 'File not assigned ';
- 103 : msg := 'File not open ';
- 104 : msg := 'File not open for input ';
- 105 : msg := 'File not open for output ';
- 106 : msg := 'Invalid numeric format ';
- 150 : msg := 'Disk is write_protected';
- 151 : msg := 'Unknown unit';
- 152 : msg := 'Drive not ready';
- 153 : msg := 'Unknown command';
- 154 : msg := 'CRC error in data';
- 155 : msg := 'Bad drive request structure length';
- 156 : msg := 'Disk seek error';
- 157 : msg := 'Unknown media type';
- 158 : msg := 'Sector not found';
- 159 : msg := 'Printer out of paper';
- 160 : msg := 'Device write fault';
- 161 : msg := 'Device read fault';
- 162 : msg := 'Hardware Failure';
- 163 : msg := 'Sharing Confilct';
- 200 : msg := 'Division by zero ';
- 201 : msg := 'Range check error ';
- 202 : msg := 'Stack overflow error ';
- 203 : msg := 'Heap overflow error ';
- 204 : msg := 'Invalid pointer operation ';
- 205 : msg := 'Floating point overflow ';
- 206 : msg := 'Floating point underflow ';
- 207 : msg := 'Invalid floating point operation ';
- 390 : msg := 'Serial Port TIMEOUT';
- 399 : msg := 'Serial Port NOT Responding';
-
- 1008 : Msg := 'EMS Memory Swap Error '
- ELSE
- GetDosErrorMessage (Msg);
- END;
- END;
-
-
- FUNCTION UserIOError(ErrNum : INTEGER; VAR IOErr : IOErrorRec) : BOOLEAN;
- { RETURN ALL INFO ABOUT THE ERROR IF IT OCCURED}
- CONST
- ErrTitles : ARRAY [1..5] OF STRING [10] =
- ('System', 'Disk', 'Network', 'Serial', 'Memory');
-
- VAR
- Msg : STRING;
- Regs : REGISTERS;
-
- BEGIN
-
- UserIOError := FALSE;
- FILLCHAR(IOErr,SizeOf(IOErr),#0);
- IF ErrNum <=0 THEN EXIT;
-
- { GET DOS Extended Error }
- WITH Regs DO
- BEGIN
- AH := $59;
- BX := $00;
- MSDOS (Regs);
- END;
-
- IOResultToErrorMessage (Regs.AX, Msg);
-
- IOErr.RoutineName := PARAMSTR (0);
- IOErr.ErrorAddr := Hex (SEG (ErrorAddr^), 4) + ':' + Hex (OFS (ErrorAddr^), 4);
- IOErr.ErrorType := ErrTitles[Regs.CH];
- IOErr.TurboResult := ErrNum;
- IOErr.IOResult := Regs.AX;
- IOErr.ErrMsg := Msg;
-
- UserIOError := (ErrNum > 0);
- END;
-
- BEGIN
- GetIntVec($24,TurboInt24);
- CriticalErrorDOS;
- END.
-
- { -------------------------- DEMO --------------------- }
-
- { EXAMPLE FOR CRITICAL ERROR HANDLER UNIT }
- { COMPILE AND RUN FROM DOS !!! WILL NOT WORK PROPERLY FROM THE IDE }
- {$I-} { A MUST FOR THE CRITICAL HANDLER TO WORK !!!! }
-
- USES
- CRT, CRITERR;
-
- VAR
- f: TEXT;
- i: INTEGER;
- ErrMsg : STRING;
- IOErr : IOErrorRec;
-
- BEGIN
- ClrScr;
- WriteLn(' EXAMPLE PROGRAM FOR CRITICAL ERROR HANDLER ');
- WriteLn;
- WriteLn('Turbo Pascal replaces the operating system''s critical-error');
- WriteLn('handler with its own. For this demonstration we will generate');
- WriteLn('a critical error by attempting to access a diskette that is not');
- WriteLn('present. Please ensure that no diskette is in drive A, then');
- WriteLn('press RETURN...');
- ReadLn;
- CriticalErrorTP;
- Assign(f,'A:NOFILE.$$$');
- WriteLn;
- WriteLn('Now attempting to access drive...');
- Reset(f);
- IF UserIOError(IOResult,IOErr) THEN
- BEGIN
- WriteLn(IOErr.RoutineName);
- WriteLn(IOErr.ErrorAddr);
- WriteLn(IOErr.ErrorType);
- WriteLn(IOErr.TurboResult);
- WriteLn(IOErr.IOResult);
- WriteLn(IOErr.ErrMsg);
- END;
- WriteLn;
- Write('Press RETURN to continue...');
- ReadLn;
- WriteLn;
- CriticalErrorDOS;
- WriteLn('With the DOS error handler restored, you will be presented');
- WriteLn('with the usual "Abort, Retry, Ignore?" prompt when such an');
- WriteLn('error occurs. (Later DOS versions allow a "Fail" option.)');
- WriteLn('Run this program several times and try different responses.');
- Write('Press RETURN to continue...');
- ReadLn;
- WriteLn('Now attempting to access drive again...');
- Reset(f);
- IF UserIOError(IOResult,IOErr) THEN
- BEGIN
- WriteLn(IOErr.RoutineName);
- WriteLn(IOErr.ErrorAddr);
- WriteLn(IOErr.ErrorType);
- WriteLn(IOErr.TurboResult);
- WriteLn(IOErr.IOResult);
- WriteLn(IOErr.ErrMsg);
- END;
- Readkey;
- END.
-